<template>
  <div class="cmap" id="mapChart"></div>
</template>

<script>
import { getMap } from "./maputils";
import chinaData from "../assets/data/china.json";
import * as echarts from "echarts";
import mapBg from "../assets/images/mapBg.png";
import lineTop1 from "../assets/images/lineTop1.png";
import lineTop2 from "../assets/images/lineTop2.png";
import lineTop3 from "../assets/images/lineTop3.png";
import lineTop4 from "../assets/images/lineTop4.png";
import lineTop5 from "../assets/images/lineTop5.png";

export default {
  data() {
    return {
      mapOption: [],
      mapName: "china",
      cityMapName: "中国",
      citylist: [{ 中国: "401200965" }],
      lastCity: {},
      chart: {},
      bgImageUrl: require("./mapBG.png"),
      markIcon: require("./circle.png"),
      mapIcon: require("./mapIcon.png"),
    };
  },
  mounted() {
    // this.initEcharts();
    this.init();
  },
  methods: {
    init() {
      // 初始化地图数据
      const [mapName, mapJson] = getMap(this.cityMapName);
      this.mapJson = mapJson;
      let option = this.getMapOption(mapName, mapJson);

      // 地图注册
      echarts.registerMap(mapName, mapJson);
      this.chart = echarts.init(document.getElementById("mapChart"));
      window.addEventListener("resize", () => {
        this.chart.resize();
      });
      this.chart.setOption(option);

      // 点击事件
      this.chart.off();
      this.chart.on("click", (params) => {
        console.log(params);
        // 阻止散点图点击事件
        if (params.seriesType === "scatter") return;
        // 暴露地图点击事件
        const { name: cityName, data } = params;
        const name = cityName || Object.keys(this.lastCity)[0];
        let code = "";
        if (params.componentType === "series") {
          code = data?.areaUniCode ? data?.areaUniCode : this.lastCity[name];
        } else {
          code = this.lastCity[name];
        }

        const [mapName, mapJson] = getMap(name);
        this.mapJson = mapJson;
        if (mapJson) {
          // 暴露点击事件
          // if (params.componentType === 'series') {
          //   this.citylist.push({ [name]: code })
          // }
          // this.mapClick(code, name)
          // 防止返回上一层点击事件进行push操作
          if (params.componentType == "geo") {
            this.citylist.push({ [name]: code });
          }
        }
        if (!mapJson) return;
        echarts.registerMap(mapName, mapJson);
        option = this.getMapOption(mapName, mapJson);
        option.geo.forEach((geoItem) => {
          geoItem.map = mapName;
        });
        this.chart.setOption(option);
        this.chart.resize();
      });
    },
    getMapOption(name, data) {
      // 渐变层颜色
      // const colorList = [
      //   "#8b5e70",
      //   "#81596d",
      //   "#78556a",
      //   "#6e5068",
      //   "#644c65",
      //   "#5b4762",
      //   "#51435f",
      //   "#483e5c",
      //   "#3e3a59",
      //   "#343557",
      //   "#2b3154",
      //   "#212c51",
      // ];
      const colorList = [
        "rgb(53, 114, 234)", // 起始颜色
        "rgb(48, 103, 210)",
        "rgb(48, 103, 210)",
        "rgb(48, 103, 210)",
        "rgb(38, 81, 162)",
        "rgb(38, 81, 162)",
        "rgb(33, 70, 138)",
        "rgb(31, 62, 124)",
        "rgb(27, 52, 104)",
        "rgb(26, 48, 98)",
        "rgb(38, 81, 162)",
      ];
      // 生成渐变图层
      const geoList = [];
      for (let i = 1; i <= colorList.length; i++) {
        const mapOption = {
          map: "china",
          aspectScale: 0.85, // 水平缩放比例
          emphasis: {
            disabled: true,
          },
          z: 12 - i,
          layoutCenter: ["50%", `${i * 0.3 + 50}%`], //地图位置
          layoutSize: "100%",
          itemStyle: {
            normal: {
              areaColor: colorList[i - 1],
              borderWidth: 0,
            },
          },
          // 设置单独的样式
          regions: [
            {
              name: "南海诸岛",
              show: false,
              itemStyle: {
                opacity: 0,
                label: {
                  show: false,
                },
              },
            },
          ],
        };
        if (i === colorList.length) {
          // mapOption.itemStyle.normal.shadowColor = "rgba(0, 0, 0, 0.71)";
          mapOption.itemStyle.normal.shadowColor = "rgba(17, 158, 255, 0.56)";
          mapOption.itemStyle.normal.shadowBlur = 100;
        }
        geoList.push(mapOption);
      }
      // 获取柱状图配置
      const lineSeriesData = this.getLineData();
      const option = {
        tooltip: {
          show: false,
          trigger: "item",
          className: "map-tooltip",
          formatter: (params) => {
            console.log(params);
            // return params.name + '<br>' + params.value;
            return `
              <div class="map-tooltip-dark">
                  <div class="map-tooltip-title">
                    ${params.name}
                  </div>
                  <div class="map-tooltip-content">
                    <div> <div class="item-text">异常运行数量<span class="num-text">${params.value}</span>个</div>
                    <div> <div class="item-text">处理单量<span class="num-text">${params.value}</span>单</div>
                    <div> <div class="item-text">通过率<span class="num-text">${params.value}</span>%</div>
                  </div>
              </div>
            `;
          },
        },
        geo: [
          // 最外围发光边界
          {
            map: "china",
            aspectScale: 0.85,
            layoutCenter: ["50%", "50%"], //地图位置
            layoutSize: "100%",
            z: 12,
            emphasis: {
              disabled: true,
            },
            itemStyle: {
              normal: {
                // borderColor: "rgb(180, 137, 81)",
                // borderWidth: 8,
                // shadowColor: "rgba(218, 163, 88, 0.4)",
                // shadowBlur: 20,
                borderColor: "rgba(50, 199, 227, 1)",
                borderWidth: 4,
                shadowColor: "#0986E6",
                shadowBlur: 10,
                shadowOffsetY: -1,
              },
            },
          },
          // 最外层遮罩蒙版
          {
            map: "china",
            aspectScale: 0.85,
            layoutCenter: ["50%", "50%"], //地图位置
            layoutSize: "100%",
            z: 14,
            label: {
              // 省份文字显示
              show: true,
              color: "#fff",
              fontSize: 14,
              // 鼠标放上去的样式
              emphasis: {
                show: true,
                textStyle: {
                  color: "#FFFFFF",
                  fontSize: 18,
                },
              },
            },
            itemStyle: {
              normal: {
                // areaColor: "rgba(106, 125, 171, 0.45)",
                areaColor: {
                  type: "image",
                  // color: 'rgba(106, 125, 171, 0.45)',
                  image: this.bgImageUrl, // 使用背景图片
                  repeat: "repeat", // 是否平铺，可以是 'repeat-x', 'repeat-y', 'no-repeat'
                  x: 15,
                  y: 10,
                },
                borderColor: "#778394",
                borderWidth: 1.2,
                // shadowColor: '#0986E6',
                // shadowBlur: 10,
                // shadowOffsetY: -1,
              },
              emphasis: {
                // areaColor: 'rgba(214, 87, 1, 1)',
                areaColor: {
                  type: "image",
                  image: this.mapIcon, // 使用背景图片
                  width: 20, // 图标宽度
                  height: 20, // 图标高度
                  repeat: "repeat", // 是否平铺，可以是 'repeat-x', 'repeat-y', 'no-repeat'
                  x: 15,
                  y: 10,
                },
                borderWidth: 2,
                opacity: 5,
              },
            },
            // 添加 graphic 配置，处理鼠标移入移出事件
            graphic: {
              elements: [],
              onmousemove: (params) => {
                if (!params.data || params.seriesType === "scatter") return;
                const geo = this.chart.getModel().getComponent("geo", 0);
                const regionName = params.name;
                const center = geo.getRegion(regionName).center;
                const coord = geo.dataToPoint(center);

                const elements = [
                  {
                    type: "image",
                    style: {
                      // 鼠标移入时使用 mapIcon
                      image: this.mapIcon,
                      width: 20,
                      height: 20,
                    },
                    position: coord,
                  },
                  {
                    type: "text",
                    style: {
                      text: regionName,
                      fill: "#fff",
                      fontSize: 16,
                      textAlign: "center",
                    },
                    position: [coord[0], coord[1] + 20],
                  },
                ];
                this.chart.setOption({
                  geo: {
                    graphic: {
                      elements,
                    },
                  },
                });
              },
              onmouseout: () => {
                // 鼠标移出时清除图标和文字
                this.chart.setOption({
                  geo: {
                    graphic: {
                      elements: [],
                    },
                  },
                });
              },
            },
          },
          // 内部蓝色边界
          {
            map: "china",
            aspectScale: 0.85,
            layoutCenter: ["50%", "50%"], //地图位置
            layoutSize: "100%",
            z: 12,
            emphasis: {
              disabled: true,
            },
            itemStyle: {
              normal: {
                areaColor: {
                  // image: mapBg,
                  image: this.bgImageUrl,
                },
                borderColor: "#8aa5db",
                borderWidth: 1,
              },
            },
          },
          ...geoList,
        ],
        series: [
          // 地图数据柱子
          ...lineSeriesData,
        ],
        graphic: {
          // 左上角操作按钮
          type: "text",
          x: 25,
          y: 25,
          style: {
            text: "返回",
            fill: "#333",
            font: 'bolder 1em "Microsoft YaHei", sans-serif',
            fontSize: 35,
          },
          // 返回按钮点击事件
          onclick: () => {
            // 利用函数的作用域，可以直接拿上面的name来用
            if (this.citylist.length < 2) return;
            this.lastCity = this.citylist[this.citylist.length - 2];
            const name = Object.keys(this.lastCity)[0];
            const [grahpName, graphJson] = getMap(name);
            // 删除最后一个元素
            this.citylist.pop();
            // 公共部分抽离出来
            echarts.registerMap(grahpName, graphJson);
            option.geo.forEach((geoItem) => {
              geoItem.map = grahpName;
              // 设置为undefined，可以保证地图切换时总是居中
              // geoItem.center = undefined;
            });
            this.chart.setOption(option);
          },
        },
      };
      return option;
    },

    // 生成地图数据柱数据
    getLineData() {
      let lineTopList = [lineTop1, lineTop2, lineTop3, lineTop4, lineTop5];
      // const districtData = [
      //   {
      //     name: "南京市",
      //     value: 267,
      //     point: [118.767413, 32.041544],
      //   },
      //   {
      //     name: "常州市",
      //     value: 200,
      //     point: [119.946973, 31.772752],
      //   },
      //   {
      //     name: "苏州市",
      //     value: 129,
      //     point: [120.619585, 31.299379],
      //   },
      //   {
      //     name: "扬州市",
      //     value: 107,
      //     point: [119.421003, 32.393159],
      //   },
      //   {
      //     name: "无锡市",
      //     value: 86,
      //     point: [120.301663, 31.574729],
      //   },
      // ];

      // 地图图标数据获取
      let districtData = [];
      this.mapJson.features.forEach(function (item, index) {
        var name = item.properties.name,
          cp = item.properties.cp;
        if (cp) {
          districtData.push({
            name: name,
            point: cp.concat(Math.round(Math.random() * 100)),
            value: 500,
          });
        }
      });
      const lineSeriesData = [];
      const maxValue = Math.max(...districtData.map((item) => item.value));
      districtData.forEach((item, index) => {
        // 柱子
        const lineData = {
          type: "lines",
          zlevel: 5,
          effect: {
            show: false,
            symbolSize: 5,
          },
          lineStyle: {
            width: 10,
            color: {
              type: "linear",
              x: 1,
              y: 0,
              x2: 0,
              y2: 0,
              colorStops: [
                {
                  offset: 0,
                  color: "rgba(232, 204, 149, 1)",
                },
                {
                  offset: 1,
                  color: "rgba(170, 144, 91, 1)",
                },
              ],
              global: false,
            },
            opacity: 1,
            curveness: 0,
          },
          label: {
            show: 0,
            position: "end",
            formatter: "245",
          },
          silent: true,
          data: [
            {
              ...item,
              coords: [
                item.point,
                [item.point[0], item.point[1] + item.value / maxValue],
              ],
            },
          ],
        };
        // 柱子顶部
        const lineTop = {
          type: "scatter",
          coordinateSystem: "geo",
          geoIndex: 0,
          zlevel: 5,
          label: {
            show: false,
          },
          symbol: "circle",
          symbolSize: [10, 5],
          itemStyle: {
            color: "rgba(255, 255, 179, 1)",
          },
          silent: true,
          data: [
            [item.point[0], item.point[1] + item.value / maxValue],
            [item.point[0], item.point[1] + item.value / maxValue],
          ],
        };
        // 柱子底部
        const lineBottom = {
          type: "scatter",
          coordinateSystem: "geo",
          geoIndex: 0,
          zlevel: 4,
          label: {
            show: false,
          },
          // symbol: "circle",
          symbol: `image://` + this.markIcon,
          symbolSize: [50, 40],
          symbolOffset: [0, 15], // 初始偏移设置
          itemStyle: {
            color: {
              type: "linear",
              x: 1,
              y: 0,
              x2: 0,
              y2: 0,
              colorStops: [
                {
                  offset: 0,
                  color: "rgba(232, 204, 149, 1)",
                },
                {
                  offset: 1,
                  color: "rgba(170, 144, 91, 1)",
                },
              ],
              global: false,
            },
          },
          silent: true,
          data: [item.point],
        };
        // *****底部光圈*****
        const lineBottomCircle = {
          name: "Top 5",
          type: "effectScatter",
          coordinateSystem: "geo",
          data: [
            {
              name: item["name"],
              value: [item.point[0], item.point[1], item["value"]],
            },
          ],
          showEffectOn: "render",
          rippleEffect: {
            scale: 5,
            brushType: "stroke",
          },
          label: {
            normal: {
              formatter: "{b}",
              position: "bottom",
              show: false,
              color: "#fff",
              distance: 10,
            },
          },
          // symbol: "circle",
          symbol: `image://` + this.markIcon,
          symbolSize: [20, 10],
          itemStyle: {
            normal: {
              color: "rgba(232, 204, 149, 1)",
              shadowBlur: 10,
              shadowColor: "rgba(232, 204, 149, 1)",
            },
            opacity: 1,
          },
          zlevel: 4,
        };
        // 顶部图标
        const lineTopIcon = {
          type: "scatter",
          coordinateSystem: "geo",
          geoIndex: 0,
          zlevel: 5,
          label: {
            normal: {
              show: true,
              formatter: function (params) {
                return `{cityName|${params.name}}\n {value|${params.data.data}} {unit|万人}`;
              },
              rich: {
                cityName: {
                  color: "rgba(201, 211, 234, 1)",
                  fontSize: 14,
                  padding: [6, 0, 4, 48],
                },
                value: {
                  color: "rgba(255, 187, 94, 1)",
                  fontSize: 18,
                  fontWeight: 800,
                  padding: [0, 0, 0, 44],
                },
                unit: {
                  color: "rgba(255, 187, 94, 1)",
                  fontSize: 14,
                },
              },
            },
            emphasis: {
              show: true,
            },
          },
          symbol: `image://` + lineTopList[index],
          symbolSize: [143, 48],
          symbolOffset: [0, 0],
          z: 999,
          data: [
            {
              name: item.name,
              data: item.value,
              value: [
                item.point[0],
                item.point[1] + item.value / maxValue + 0.2,
              ],
            },
          ],
        };
        // lineSeriesData.push(lineData); // 柱子
        // lineSeriesData.push(lineTop); // 柱子顶部
        lineSeriesData.push(lineBottom); // 柱子底部
        // lineSeriesData.push(lineBottomCircle);
        // lineSeriesData.push(lineTopIcon);
      });
      return lineSeriesData;
    },
  },
};
</script>

<style lang="scss" scoped>
.cmap {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #0f1e33;
}

::v-deep .map-tooltip {
  height: 230px;
  width: 200px;
  background: url("./map-tooltip-dark.png") no-repeat;
  background-size: 100% 100%;
  .map-tooltip-dark {
    color: #fff !important;
    font-size: 16px;
  }
  .item-text {
    width: 100px;
  }
}
</style>
